#ifndef __INCLUDED_CBL_RTTI_H__
#error "CBL_Rtti.hpp must not be used directly. Use CBL_Rtti.h instead."
#else
#ifndef __INCLUDED_CBL_RTTI_HPP__
#define __INCLUDED_CBL_RTTI_HPP__

// --------------------------------------------------------------------------------------------------------------------
//  compiler specific implementations
// --------------------------------------------------------------------------------------------------------------------

#ifdef CB_GCC

// ----------------------------------------------------------------------------------------------------------------
//  GCC
// ----------------------------------------------------------------------------------------------------------------

#include <cxxabi.h>
CB_SUBNAMESPACE_START(RTTI)

template <typename TType>
CB_FORCEINLINE const char* CB_INLINE_ATTR GetClassName(const TType* _pObject)
{
    try
    {
    	return abi::__cxa_demangle(typeid(*_pObject).name(), NULL, 0, NULL);
    }
    	catch (std::bad_typeid)
    {
    	return "NULL";
    }
    
    return NULL;
}

// --------------------------------------------------------------------

template <typename TType>
CB_FORCEINLINE const char* CB_INLINE_ATTR GetClassName(const TType& _rObject)
{
    try
    {
   		return abi::__cxa_demangle(typeid(_rObject).name(), NULL, 0, NULL);
    }
    	catch (std::bad_typeid)
    {
    	return "NULL";
    }
    
    return NULL;
}

// --------------------------------------------------------------------

template <typename TType>
CB_FORCEINLINE const char* CB_INLINE_ATTR GetClassName()
{
    return abi::__cxa_demangle(typeid(TType).name(), NULL, 0, NULL);
}

// --------------------------------------------------------------------

CB_FORCEINLINE const char* CB_INLINE_ATTR Demangle(const char* _pName)
{
    return abi::__cxa_demangle(_pName, NULL, 0, NULL);
}

#elif defined(CB_MSC)

// ----------------------------------------------------------------------------------------------------------------
//  MSC
// ----------------------------------------------------------------------------------------------------------------

#include <typeinfo>
CB_SUBNAMESPACE_START(RTTI)

template <typename TType>
CB_FORCEINLINE const char* CB_INLINE_ATTR GetClassName(const TType* _pObject)
{
    try
    {
    	return typeid(*_pObject).name();
    }
    	catch (std::bad_typeid)
    {
    	return "NULL";
    }
    
    return NULL;
}

// --------------------------------------------------------------------

template <typename TType>
CB_FORCEINLINE const char* CB_INLINE_ATTR GetClassName(const TType& CB_UNUSED(_rObject))
{
    try
    {
    	return typeid(TType).name();
    }
    catch (std::bad_typeid)
    {
    }
    
    return "NULL";
}

// --------------------------------------------------------------------

template <typename TType>
CB_FORCEINLINE const char* CB_INLINE_ATTR GetClassName()
{
    return typeid(TType).name();
}

// --------------------------------------------------------------------

CB_FORCEINLINE const char* CB_INLINE_ATTR Demangle(const char* _pName)
{
    return _pName;
}

#else

#error "RTTI functionality not available for this compiler."

#endif

CB_SUBNAMESPACE_END

#endif
#endif